﻿using System.Diagnostics;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using ORS.OrderRobot.IOC;
using ORS.OrderRobot.Service.Helper;
using ORS.OrderRobot.Service.Jobs;
using ORS.OrderRobot.ServiceContracts;
using ORS.OrderRobot.ServiceContracts.Dtos;
using ORS.OrderRobot.ServiceContracts.Dtos.Api;
using ORS.OrderRobot.ServiceContracts.ThridPartApi;

namespace ORS.OrderRobot.Service
{
	public class AccountLoginService: IAccountLoginService,IScoped
    {
        private readonly ILogger<AccountLoginService> _logger;
        private readonly IHubContext<MessageHub> _hubContext;
        private readonly IAccountService _accountService;
        private readonly IThirdAccountService _thridAccountService;
        private readonly IThirdBasketService _thirdBasketService;
        private readonly IBackgroundJobManager _backgroundJobManager;
        private readonly ISystemConfigService _systemConfigService;
        private readonly AccountCacheManager _accountCacheManager;
        private readonly LockCacheManager _lockCacheManager;
        public AccountLoginService(
            ILogger<AccountLoginService> logger,
            IThirdAccountService thridAccountService,
            IAccountService accountService,
            IThirdBasketService thirdBasketService,
            IBackgroundJobManager backgroundJobManager,
            ISystemConfigService systemConfigService,
            IHubContext<MessageHub> hubContext,
            AccountCacheManager accountCacheManager,
            LockCacheManager lockCacheManager
        )
        {
            _logger = logger;
            _hubContext = hubContext;
            _thridAccountService = thridAccountService;
            _thirdBasketService = thirdBasketService;
            _accountService = accountService;
            _backgroundJobManager = backgroundJobManager;
            _systemConfigService = systemConfigService;
            _accountCacheManager = accountCacheManager;
            _lockCacheManager = lockCacheManager;
        }
        /// <summary>
        /// 用户批量登陆
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<List<string>> AutoLoginAsync()
        {
            var systemConfig = await _systemConfigService.GetConfigAsync();
            var allAcountCache = await _accountCacheManager.GetAccounts();

            // 如果缓存中没有数据，则从数据库获取数据并更新缓存
            if (allAcountCache == null || !allAcountCache.Any())
            {
                var allAcount = await _accountService.GetAllAsync(new GetAllInput { IsActive = true });
                allAcountCache = allAcount.Where(x=>x.CurrentBoarding!=null)
                    .ToDictionary(x => x.Email, x => x.Password);
                await _accountCacheManager.SetAccounts(allAcountCache);
            }

            // 异步执行所有的登录操作
            var loginTasks = allAcountCache.Select(account => LoginAsync(account.Key, account.Value)).ToList();

            // 等待所有登录任务完成
            await Task.WhenAll(loginTasks);
            var emails = await GetLoginedAccounts();
            return emails;
        }
        /// <summary>
        /// 指定用户登录
        /// </summary>
        /// <param name="email"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public async Task<LoginResultInfo?> LoginAsync(string email, string password)
        {
            var timeWatch = new Stopwatch();
            timeWatch.Start();

            var lockValue = Guid.NewGuid().ToString();
            var pollInterval = 100; // 轮询间隔
            var maxWaitTime = 2 * 60* 1000; // 最长等待2分钟
            var waited = 0;

            // 负责加锁和等待结果
            while (true)
            {
                var existingLock = await _lockCacheManager.GetLoginLock(email);
                if (string.IsNullOrEmpty(existingLock))
                {
                    // 获取锁
                    await _lockCacheManager.SetLoginLock(email, lockValue, maxWaitTime);
                    break;
                }
                // 已有锁，轮询等待
                await Task.Delay(pollInterval);
                waited += pollInterval;
                if (waited >= maxWaitTime)
                {
                    // 超时，直接返回缓存中的结果
                    var cachedResult = await _accountCacheManager.GetLogin(email);
                    return cachedResult;
                }
                //pollInterval = Math.Max(pollInterval - 5, minPollInterval);
            }

            try
            {
                await MsgHelper.SendAsync(_hubContext,new MsgData { Obj = email,Action ="开始登录"});

                var systemConfig = await _systemConfigService.GetConfigAsync();
                var data = await _thridAccountService.LoginAsync(email, password);
                var loginedTime = DateTime.Now.China();
                if (data != null && !string.IsNullOrEmpty(data.Token))
                {
                    try
                    {
                        //获取用户的购物车
                        var basketInfo = await _thridAccountService.GetAccountBasketAsync(new GetCustomerCartInput
                        {
                            CustomerId = data.CustomerId,
                            Token = data.Token
                        });
                        data.BasketId = basketInfo.Baskets.First().BasketId;
                    }
                    catch (CodeException)
                    {
                        var createBasketInput = new CreateBasketInput
                        {
                            customer_info = new BasketUserInfo
                            {
                                customer_id = data.CustomerId,
                                customer_no = data.CustomerNo,
                                customer_name = $"{data.FirstName} {data.LastName}",
                                email = email
                            }
                        };
                        var basketDto = await _thirdBasketService.CreateBasket(createBasketInput,new CommonInput { Email = email,Token =data.Token,BasketId = "" });
                        data.BasketId = basketDto.BasketId;
                    }
                    await _accountCacheManager.SetLogin(email, data);
                    await _backgroundJobManager.EnqueueAsync<UpdateLocalLoginTimeJob, UpdateLocalLoginTimeArgs>(
                        new UpdateLocalLoginTimeArgs { CreateTime = loginedTime,Email = email}
                    );
                }
                timeWatch.Stop();
                await MsgHelper.SendAsync(_hubContext,new MsgData { Obj = email,Action ="完成登录",UsedTime = timeWatch.ElapsedMilliseconds });
                return data;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"用户 {email} 登录过程中发生异常");
                await MsgHelper.SendAsync(_hubContext,new MsgData { Obj = email,Action = $"登录失败:{ex.Message}"});
                throw;
            }
            finally
            {
                // 释放锁（只有自己加的锁才能释放）
                try
                {
                    var currentLock = await _lockCacheManager.GetLoginLock(email);
                    if (currentLock == lockValue)
                    {
                        await _lockCacheManager.RemoveLoginLock(email);
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, $"释放用户 {email} 登录锁时发生异常");
                }
            }
        }
        /// <summary>
        /// 从缓存中获取登录信息
        /// </summary>
        /// <param name="email"></param>
        /// <returns></returns>
        public async Task<LoginResultInfo?> GetLoginInfoAsync(string email)
        {
            var loginUserInfo = await _accountCacheManager.GetLogin(email);
            return loginUserInfo;
        }
        /// <summary>
        /// 更新缓存中的用户信息
        /// </summary>
        /// <param name="resultInfo"></param>
        /// <returns></returns>
        public async Task UpdateLoginCacheInfoAsync(LoginResultInfo resultInfo)
        {
            var email = resultInfo.Email;
            var loginUserInfo = await _accountCacheManager.GetLogin(email) ;
            if (loginUserInfo!=null)
            {
                var token = loginUserInfo.Token;
                resultInfo.Token = token;
                await _accountCacheManager.SetLogin(email,resultInfo);
            }
            else
            {
                throw new Exception($"缓存中无{resultInfo.Email}用户，未更新");
            }
        }
        /// <summary>
        /// 获取已登录的邮箱列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<string>> GetLoginedAccounts(bool onlyBoarding = true)
        {
            var loginKeys = await _accountCacheManager.GetAllLoginKeys();
            var boardings = await _accountCacheManager.GetAllBoarding();
            var loginEmails = loginKeys.Select(s => s.Split("|").Last()).ToList();
            var boardingEmails = boardings.Select(s => s.Email).ToList();
            if (onlyBoarding)
            {
                // 只返回在boardingEmails中存在的邮箱
                return loginEmails.Where(email => boardingEmails.Contains(email)).ToList();
            }
            
            return loginEmails;
        }
    }
}

